import { Injectable, ExecutionContext, UnauthorizedException } from '@nestjs/common'
import { AuthGuard } from '@nestjs/passport'
import { Reflector } from '@nestjs/core'
import { Observable } from 'rxjs'

/**
 * JWT 认证守卫
 * 用于保护需要认证的路由
 */
@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {
  constructor(private readonly reflector: Reflector) {
    super()
  }

  /**
   * 判断是否可以激活路由
   * @param context 执行上下文
   * @returns 是否可以访问
   */
  canActivate(context: ExecutionContext): boolean | Promise<boolean> | Observable<boolean> {
    // 检查是否标记为公开路由
    const isPublic = this.reflector.getAllAndOverride<boolean>('isPublic', [context.getHandler(), context.getClass()])

    if (isPublic) {
      return true
    }

    return super.canActivate(context)
  }

  /**
   * 处理请求
   * @param err 错误信息
   * @param user 用户信息
   * @param info 附加信息
   * @returns 用户信息
   */
  handleRequest(err: any, user: any, info: any) {
    if (err || !user) {
      if (info?.name === 'TokenExpiredError') {
        throw new UnauthorizedException('Token 已过期，请重新登录')
      }
      if (info?.name === 'JsonWebTokenError') {
        throw new UnauthorizedException('无效的 Token')
      }
      if (info?.name === 'NotBeforeError') {
        throw new UnauthorizedException('Token 尚未生效')
      }
      throw err || new UnauthorizedException('认证失败')
    }
    return user
  }
}
